/**
 * @file w5100.h
 * @brief Declares functions that operate on the Wiznet W5100 ethernet 
 *        device.
 * @author Vamshi Ponnapalli
 */

#ifndef _W5100_H
  #define _W5100_H
  /*****************************************************************************
   * Includes
   ****************************************************************************/
  #include "hal_types.h"
  #include "hal_defs.h"
  #include "network.h"

  #ifdef __cplusplus
    extern "C" {
  #endif

  /*****************************************************************************
   * Types
   ****************************************************************************/
   /**
    * A structure that stores socket specific information.
    */
   typedef struct
   {
     uint8 state;          //The socket state (TCP, UDP, Closed, etc)
     uint16 rxAddressBase; //Base address of Rx memory
     uint16 rxAddressMask; //Rx address mask (used to calc Rx addresses)
     uint16 txAddressBase; //Base address of Tx memory
     uint16 txAddressMask; //Tx address mask (used to calc Rx addresses)
   } socket_info_t;


  /*****************************************************************************
   * Constants
   ****************************************************************************/
  //Register addresses  
  #define W5100_REG_GATEWAY_ADDR   0x0001
  #define W5100_REG_SUBNET_MASK    0x0005
  #define W5100_REG_HARDWARE_ADDR  0x0009
  #define W5100_REG_IP_ADDR        0x000F
  #define W5100_REG_INTERRUPT      0x0015
  #define W5100_REG_INTERRUPT_MASK 0x0016
  #define W5100_REG_RX_BUF_SIZE    0x001A
  #define W5100_REG_TX_BUF_SIZE    0x001B

  /**
   * Socket specific register addresses. The actual register address for a 
   * specific port can be obtained by adding 
   * (W5100_SCK_REG_OFFSET * socket) to the register values defined 
   * below, where the value of socket can be 0, 1, 2 or 3.
   */  
  #define W5100_SOCK_REG_OFFSET          0x0100 
  #define W5100_REG_SOCK_MODE(socket)    0x0400 +\
                                             (W5100_SOCK_REG_OFFSET * socket)
  #define W5100_REG_SOCK_CMD(socket)     0x0401 +\
                                             (W5100_SOCK_REG_OFFSET * socket)
  #define W5100_REG_SOCK_INT(socket)     0x0402 +\
                                             (W5100_SOCK_REG_OFFSET * socket)
  #define W5100_REG_SOCK_STAT(socket)    0x0403 +\
                                             (W5100_SOCK_REG_OFFSET * socket)
  #define W5100_REG_LOCAL_PORT(socket)   0x0404 +\
                                             (W5100_SOCK_REG_OFFSET * socket)
  #define W5100_REG_DEST_PORT(socket)    0x0410 +\
                                             (W5100_SOCK_REG_OFFSET * socket)
  #define W5100_REG_DEST_IP_ADDR(socket) 0x040C +\
                                             (W5100_SOCK_REG_OFFSET * socket)
  #define W5100_REG_TX_FREE_MEM(socket)  0x0420 +\
                                             (W5100_SOCK_REG_OFFSET * socket)
  #define W5100_REG_TX_WRITE_PTR(socket) 0x0424 +\
                                             (W5100_SOCK_REG_OFFSET * socket)
  #define W5100_REG_RX_DATA_SIZE(socket) 0x0426 +\
                                             (W5100_SOCK_REG_OFFSET * socket) 
  #define W5100_REG_RX_READ_PTR(socket)  0x0428 +\
                                             (W5100_SOCK_REG_OFFSET * socket)
  
  //Socket size values    
  #define W5100_SOCK_SIZE_1KB      0x00
  #define W5100_SOCK_SIZE_2KB      0x01
  #define W5100_SOCK_SIZE_4KB      0x02
  #define W5100_SOCK_SIZE_8KB      0x03
  
  //Socket mode values
  #define W5100_SOCK_MODE_CLOSED   0x00
  #define W5100_SOCK_MODE_TCP      0x01
  #define W5100_SOCK_MODE_UDP      0x02
  #define W5100_SOCK_MODE_IPRAW    0x03
  
  //Socket command values
  #define W5100_SOCK_CMD_OPEN      0x01
  #define W5100_SOCK_CMD_CONNECT   0x04
  #define W5100_SOCK_CMD_CLOSE     0x10
  #define W5100_SOCK_CMD_SEND      0x20
  #define W5100_SOCK_CMD_RECV      0x40  
   
  //Socket interrupt flags
  #define W5100_SOCK_INT_FLAG_RECV 0x04   
  
  //Socket state values
  #define W5100_SOCK_STATE_CLOSED  0x00
  #define W5100_SOCK_STATE_ESTD    0x17
  #define W5100_SOCK_STATE_UDP     0x22
  #define W5100_SOCK_STATE_INIT    0x13 

  //Addressing related value (mask/base address)
  #define W5100_MASK_BASE          0x0400
  #define W5100_RX_ADDRESS_BASE    0x6000
  #define W5100_TX_ADDRESS_BASE    0x4000
  
  #ifdef __cplusplus
    }
  #endif

#endif
